<?php
/* [DoYouHaoBaby!] (C)Dianniu From 2010.
   this($)*/

!defined('DYHB_PATH') && exit;

// 导入接口
Package::importI('ITemplateAutoloadableProcessor','TEMPLATE');

class TemplateGtkGladeWidgetParser extends TemplateObjParserBase implements ITemplateAutoloadableProcessor{

	static private $_arrCompilerDirs=array();

	public function __construct(){
		$oCompilerManager=new TemplateObjProcessorManager();
		foreach(self::$_arrCompilerDirs as $sDir){// 自动载入 编译器目录下的 所有 编译器
			$oCompilerManager->autoloadProcessor($sDir);
		}
		$this->setCompilerManager($oCompilerManager);
	}

	public function parse(Template $oTemplate,$sTemplatePath,&$sCompiled){
		A::STRING($sCompiled);
		$oDocument=simplexml_load_string($sCompiled);
		if($oDocument===false){
			G::E(G::L('Glade 窗口模版文件存在错误。','Dyhb',null));
		}
		$arrWindows=$oDocument->children();
		foreach($arrWindows as $oWindowNode){
			$oWindowWidget=$this->processWidget_($oWindowNode,$oTemplate);
			$oTemplate->putInTemplateObj($oWindowWidget);
		}
	}

	public function processWidget_(SimpleXMLElement $oWidgetNode, Template $oTemplate){
		$sWidgetClass=strval($oWidgetNode['class']);
		$oWidget=new TemplateGtkGladeWidget($sWidgetClass,strval($oWidgetNode['id']));
		$oWidget->setTemplate($oTemplate);// 装配Template对象
		$oWidget->setParser($this);
		$oCompiler=$this->queryCompilerByNodeName($sWidgetClass);
		A::INSTANCE($oCompiler,'ITemplateObjCompiler');
		$oWidget->setCompiler($oCompiler);
		$arrPropertyNodes=$oWidgetNode->xpath('property');// 属性
		foreach($arrPropertyNodes as $oPropertyNode){
			$oProperty=new TemplateGtkGladeWidgetProperty(strval($oPropertyNode['name']),strval($oPropertyNode));
			foreach($oPropertyNode->_arrAttributes as $sName=>$sValue){// 依次设置 Property 节点的属性
				if(strtolower($sName)=='name'){
					continue;
				}
				$oProperty->set($sName,$sValue);
			}
			$oWidget->addProperty($oProperty);
		}
		$arrSignalNodes=$oWidgetNode->xpath('signal');// 信号事件
		foreach($arrSignalNodes as $oSignalNode){
			$oWidget->addSignal(
				$oSignalNode['name'],$oSignalNode['handler'],
				isset($oSignalNode['object'])?$oSignalNode['object']:null,
				TemplateGtkGladeObj::nodeTextToValue(isset($oSignalNode['after'])?(string)$oSignalNode['after']:'no')
			);
		}
		$arrChildrenNode=$oWidgetNode->xpath('child');// 下级子窗体
		foreach($arrChildrenNode as $oChildNode){
			$arrChildWidget=$oChildNode->xpath('widget');
			if(!isset($arrChildWidget[0])){// 空位
				continue;
			}
			$oChildWidget=$this->processWidget_($arrChildWidget[0],$oTemplate);
			$oPacking=new TemplateGtkGladeWidgetPacking();// 打包方式
			$arrChildPacking=$oChildNode->xpath('packing');// 依次处理 Packing 的  Property
			if(isset($arrChildPacking[0])){
				$arrPackingPropertys=$arrChildPacking[0]->xpath('property');
				foreach($arrPackingPropertys as $oPropertyNode){
					$oProperty=new TemplateGtkGladeWidgetProperty(strval($oPropertyNode['name']), strval($oPropertyNode));
					foreach($oPropertyNode->_arrAttributes as $sName=>$sValue){// 依次设置 Property 节点的属性
						if(strtolower($sName)=='name'){
							continue;
						}
						$oProperty->set($sName,$sValue);
					}
					$oPacking->addProperty($oProperty);// 加入到 packing 对象中
				}
			}
			$oWidget->addTemplateObj($oChildWidget,$oPacking);
		}
		return $oWidget;
	}

	public function queryCompilerByNodeName($sWidgetClass){
		A::STRING($sWidgetClass);
		$oManager=$this->getCompilerManager();
		A::INSTANCE($oManager,'ITemplateObjProcessorManager');
		$sClass=$sWidgetClass;
		while($sClass){
			if($oCompiler=$oManager->getProcessor($sClass)){
				return $oCompiler;
			}
			$sClass=get_parent_class($sClass);
		}
		G::E(G::L('无法为：“%s”类型的窗体(Widget)找到编译器','Dyhb',null));
	}

	static public function addCompilerDir($sDir){
		A::DDIR($sDir);
		$sDirPath=G::tidyPath($sDir);
		if(!in_array($sDirPath,self::$_arrCompilerDirs)){
			self::$_arrCompilerDirs[]=$sDirPath;
		}
	}

	static public function clearCompilerDir(){
		$nCount=count(self::$_arrCompilerDirs);
		self::$_arrCompilerDirs=array();
		return $nCount;
	}

	static public function regToProcessorManager(ITemplateObjProcessorManager $oManager){
		$oManager->regProcessor('Template.Gtk.Glade', __CLASS__);
	}

}

/** 添加编译目录 */
TemplateGtkGladeWidgetParser::addCompilerDir(dirname(__FILE__).'/TemplateGtkGladeWidgetCompiler/');
